package src.view;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Point;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;

import javax.imageio.ImageIO;

import src.event.EventHandler;
import src.event.EventListener;
import src.event.events.ConsoleUpdateEvent;
import src.view.ViewHandler.DisplayType;
import src.view.ViewHandler.ImageType;

/**
 * <b>Overview</b>
 * The ConsoleViewport is responsible for displaying a textual representation of in-game events.  It will keep a history of several events so the user may see what has happened over several actions.  This viewport appears on the main view at the bottom left.
 *
 * <b>Responsibilities</b>
 * Maintain past actions, display list of recent actions to canvas.
 *
 * <b>Collaborators</b>
 * Drawable - Client: the Drawable canvas must display the graphical representation of the Console.
 *
 * <b>Implementor</b> - Bruce
 * <b>Tester</b> - Tim
 *
 * @author Bruce
 */
public class ConsoleViewport extends Viewport implements EventListener<ConsoleUpdateEvent>
{
	/**
	 * The height of each line in pixels.
	 */
	private static final int LINE_SIZE = 20;

	/**
	 * The maximum number of lines to display at one time.
	 */
	private static final int LINE_NUM = 5;

	/**
	 * Adjustment needed for windows... for some reason.
	 */
	private static final int ADJUSTMENT = -35;

	/**
	 * The list of messages to display.
	 */
	private ArrayList<String> messages = new ArrayList<String>();

	/**
	 * The first line in the display, as an offset.
	 */
	private int offset = 0;

	/**
	 * Creates a new ConsoleViewport.
	 *
	 * @param canvas the Drawable object on which to display the console.
	 */
	public ConsoleViewport(ViewHandler vh, Drawable canvas)
	{
		super(vh, canvas, DisplayType.MAIN);
		EventHandler<ConsoleUpdateEvent> handler = new EventHandler<ConsoleUpdateEvent>();
		ViewEventHandler.setConsoleListener(handler);
		handler.regesterListener(this);
	}

	/* (non-Javadoc)
	 * @see src.event.EventListener#eventCallback(src.event.Event)
	 */
	public boolean eventCallback(ConsoleUpdateEvent e)
	{
		messages.add(e.getConsoleOutput());
		if(messages.size() > LINE_NUM)
			++offset;
		refresh(DisplayType.MAIN);
		return true;
	}

	/* (non-Javadoc)
	 * @see src.view.Viewport#draw()
	 */
	@Override
	protected void draw()
	{
		// Resource bar
		BufferedImage image;
		AffineTransform at;

		image = getImage(ImageType.WOOD);
		at = new AffineTransform();
		at.scale((double)getWidth() / (double)image.getWidth(), (double)getHeight() / (double)image.getHeight());
		getCanvas().drawImage(image, at, null);

		image = getImage(ImageType.PANEL);
		at = new AffineTransform();
		at.scale((double)getWidth() / (double)image.getWidth(), 1.0);
		getCanvas().drawImage(image, at, null);

		image = getImage(ImageType.RUM);
		getCanvas().drawImage(image, 5, 10, null);
		image = getImage(ImageType.GOLD);
		getCanvas().drawImage(image, 170, 10, null);
		image = getImage(ImageType.LUMBER);
		getCanvas().drawImage(image, 345, 10, null);

		// Scroll bar
		image = getImage(ImageType.SCROLLBAR);
		getCanvas().drawImage(image, getWidth() - image.getWidth(), 0, null);
		image = getImage(ImageType.ARROWUP);
		int upHeight = image.getHeight();
		getCanvas().drawImage(image, getWidth() - image.getWidth(), 0, null);
		image = getImage(ImageType.ARROWDOWN);
		int downHeight = image.getHeight();
		getCanvas().drawImage(image, getWidth() - image.getWidth(), getHeight() - image.getHeight() + ADJUSTMENT, null);
		image = getImage(ImageType.POINT);
		double pos = messages.size() - LINE_NUM;
		if(pos <= 0)
			pos = 0.0;
		else
			pos = offset / pos;
		pos *= (getHeight() - upHeight  - downHeight - image.getHeight() + ADJUSTMENT);
		pos += upHeight;
		getCanvas().drawImage(image, getWidth() - image.getWidth(), (int)pos, null);

		if(messages != null)
			for(int x = 0; x < LINE_NUM && messages.size() > x + offset; ++x)
				drawString(messages.get(x + offset), 50, 65 + LINE_SIZE * x);

		drawString("Rum: 0", 35, 20);
		drawString("Gold: 0", 205, 20);
		drawString("Lumber: 0", 375, 20);
	}

	@Override
	protected Dimension getResizeDimension()
	{
		return new Dimension(getCanvasDimensions().width - 200, 200);
	}

	@Override
	protected Point2D getResizePoint()
	{
		return new Point2D(0, getCanvasDimensions().height - 200);
	}

	protected void click(Point p)
	{
		if(p.getX() >= getWidth() - 15)
			if(p.getY() <= 20) //Scroll up
			{
				if(offset > 0)
				{
					offset -= 1;
					refresh(DisplayType.MAIN);
				}
			}
			else if(p.getY() >= 145) //Scroll down
				if(offset + LINE_NUM < messages.size())
				{
					offset += 1;
					refresh(DisplayType.MAIN);
				}
	}

	public String toString()
	{
		return "Console";
	}
}